package com.team.RunsFast_Api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.team.RunsFast_Api.dao.*;
import com.team.RunsFast_Api.dto.*;
import com.team.RunsFast_Api.service.intf.OrderService;
import com.team.RunsFast_Api.service.intf.UserLevelService;
import com.team.runsfast.entity.*;
import com.team.runsfast.vo.R;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.*;
@Service
public class OrderServiceImpl implements OrderService {
    private final OrderDao dao;
    private final CartDao cartDao;
    private final FoodDao foodDao;
    private final UserLevelService userlevelService;
    private final OrderLogDao orderlogDao;
    private final UserLevelDao userlevelDao;
    private final OrderItemDao orderitemDao;
    private final UserMsgDao usermsgDao;
    private final ScoreLogDao scorelogDao;
    private final StoreDao storeDao;
    private final CouponDao couponDao;
    private final OrderDao orderDao;

    public OrderServiceImpl(OrderDao dao, CartDao cartDao, FoodDao foodDao, UserLevelService userlevelService, OrderLogDao orderlogDao, UserLevelDao userlevelDao, OrderItemDao orderitemDao, UserMsgDao usermsgDao, ScoreLogDao scorelogDao, StoreDao storeDao, CouponDao couponDao, OrderDao orderDao) {
        this.dao = dao;
        this.cartDao = cartDao;
        this.foodDao = foodDao;
        this.userlevelService = userlevelService;
        this.orderlogDao = orderlogDao;
        this.userlevelDao = userlevelDao;
        this.orderitemDao = orderitemDao;
        this.usermsgDao = usermsgDao;
        this.scorelogDao = scorelogDao;
        this.storeDao = storeDao;
        this.couponDao = couponDao;
        this.orderDao = orderDao;
    }

    @Override
    public R save(Order obj) {
        if(dao.insert(obj)>0){
            return R.ok();
        }else {
            return R.fail();
        }
    }

    @Override
    public R queryAll() {
        return R.ok(dao.selectList(null));
    }

    @Override
    public R queryPre(OrderPreDto dto, String token) {

        if (dto != null) {
            List<CartFoodDto> cartFoodDtos = new ArrayList<>();
            if (dto.getType() == 1) {
                //type为一则为直接下单
                cartFoodDtos = foodDao.selectByids(dto.getIds());
            } else {
                //在购物车中下单
                cartFoodDtos = cartDao.selectByids(dto.getIds());
            }

            //查询收货地址
            UserLevelAddressDto userLevelAddressDto = userlevelDao.selectAddress(Long.parseLong(token));

            //拼装收获地址
            HashMap map1 = new HashMap<>();
            map1.put("id", userLevelAddressDto.getId());
            map1.put("receive", userLevelAddressDto.getName() + "    " + userLevelAddressDto.getPhone());
            map1.put("detail", userLevelAddressDto.getCity() + "市" + userLevelAddressDto.getCountry() + "县");


            HashMap map2 = new HashMap<>();
            map2.put("level",userLevelAddressDto.getLevel());
            map2.put("score",userLevelAddressDto.getScore());

            HashMap map3=new HashMap();
            map3.put("address",map1);
            map3.put("userlevel",map2);
            map3.put("foods",cartFoodDtos);
            map3.put("type",dto.getType());
            map3.put("cids",dto.getType()==2?dto.getIds():null);
            return R.ok(map3);
        }
        return R.fail();
    }

    @Override
    @Transactional(rollbackFor = SQLException.class)
    public synchronized R createOrder(OrderAddDto dto, String token) {
        Long uid = Long.parseLong(token);
        if(Objects.nonNull(dto)){
            Order order = new Order();
            ArrayList<OrderItem> items = new ArrayList<>();
            HashMap<Long,Double> hashMap = new HashMap<>();
//            HashMap<Long,Integer> storenume = new HashMap<>();
            for(Food food:dto.getFoods()){
                //根据店铺计算每家店铺的商品购买金额
                if(hashMap.containsKey(food.getSid())){
                    hashMap.put(food.getSid(),hashMap.get(food.getSid())+food.getCurrentprice()*food.getNum());
                }else {
                    hashMap.put(food.getSid(),food.getOrginprice());
                }
                //查询用户购买的商品金额是否满足每个店铺的起送价
                for (Map.Entry<Long, Double> longDoubleEntry : hashMap.entrySet()) {
                    Long key = longDoubleEntry.getKey();
                    List<Store> stores = storeDao.selectPost(key,longDoubleEntry.getValue());
                    if(Objects.isNull(stores)){
                        return R.fail("不符合商家的起送要求");
                    }
                }
                //积累金额
                order.setMoney(order.getMoney()+food.getCurrentprice()*food.getNum()+food.getNum()*food.getPackprice());
                //每个菜品生成订单详情
                items.add(new OrderItem(0L,food.getId(),food.getNum(),food.getCurrentprice()*food.getNum()+food.getNum()*food.getPackprice(),0.0));
            }
            UserLevel userLevel = userlevelDao.selectOne(new QueryWrapper<UserLevel>().eq("uid", uid));
            if(userLevel.getScore()<dto.getScore()){
                //用户余额积分不足以抵扣
                return R.fail("亲，积分不足，不能抵扣");
            }
            //查询优惠券
            Coupon coupon ;
            if(dto.getCouponid()>0){
                coupon = couponDao.selectById(dto.getCouponid());
                //总金额大于最低金额
                if(order.getMoney()<coupon.getStintmoney()){
                    //总金额不够
                    return R.fail("亲，没有到达"+coupon.getStintmoney()+"的金额，不能使用优惠券噢");
                }
            }else {
                coupon = new Coupon();
            }
            //计算支付金额：总金额-抵扣积分的金额-优惠券的金额
            order.setPid(dto.getCouponid());
            order.setPaymoney(order.getMoney()-(userLevel.getScore()-20)/100.0-coupon.getDiscountprice());
            //计算优惠比例
            double v = order.getPaymoney() / order.getMoney();
            //设置订单信息
            order.setUid(uid);
            order.setInfo(dto.getInfo());
            order.setCtime(new Date());
            order.setFlag(1);
            order.setAid(dto.getAid());
            //12.订单号 不重复
            order.setNo(dto.getNo());
            //操作数据库，新增订单数据
            if(dao.insert(order)>0){
                items.forEach(oi->{
                    oi.setOid(order.getId());
                    //15.优惠金额  根据金钱的比例 分摊优惠
                    if(userLevel.getScore()>0){
                        //计算优惠,包括积分和优惠券
                        oi.setFreemoney(oi.getPrice()*(1-v)+coupon.getDiscountprice()*(oi.getPrice()/order.getMoney()));
                    }
                    //16.新增订单详情
                    orderitemDao.insert(oi);
                });
            }
            //18.用户等级
            userlevelService.updateLevel(uid,-20);
            //19.积分变化
            scorelogDao.insert(new ScoreLog(uid, 2, "下单，使用积分抵扣", dto.getScore()));
            //20.订单流水表
            orderlogDao.insert(new OrderLog(order.getId(),1,"创建订单成功，通过"+dto.getType()));
            //21.系统消息
            usermsgDao.insert(new UserMsg(uid,2,"亲，下单成功，快来付款！"));
            //22.购物车下单  回删购物车
            if(dto.getType()==2) {
                cartDao.deleteBatchIds(dto.getCids());
            }
            return R.ok(order);
        }
        return R.fail();
    }

    //修改订单状态
    @Override
    public R updateNo(Integer flag, String no) {
        if(Objects.nonNull(orderDao.selectList(new QueryWrapper<Order>().eq("no",no)))){
            if(orderDao.updateState(flag,no)>0){
                return R.ok(null);
            }
        }
        return R.fail();
    }

    //查询该用户所有的订单信息
    @Override
    public R queryAll(String token) {
        Long uid = Long.parseLong(token);
        List<Order> orders = orderDao.selectList(new QueryWrapper<Order>().eq("uid", uid).eq("flag", 1));
        List<Object> list = new ArrayList<>();
        //先去查每个食物列表

        for(Order order :orders){
            HashMap<Object,Object> map = new HashMap<>();
            List<OrderFoodDto> orderFoodDtos = orderDao.listOrderFood(order.getId());
            List<CouponDto> dtos;
            if(order.getPid()>0){
                dtos = couponDao.selectByIds(order.getPid());
            }else {
                dtos = new ArrayList<>();
            }

            OrderAddressDto orderAddress = orderDao.listAddressDto(uid, order.getId());
            map.put("address",orderAddress);
            map.put("foodCoupondto",new QueryDto(orderFoodDtos,dtos));
            list.add(map);
        }
        return R.ok(list);
    }

    //查询该用户所有的订单信息
    @Override
    public R queryNum(String token) {
        Long uid = Long.parseLong(token);
        List<Order> orders = orderDao.selectList(new QueryWrapper<Order>().eq("uid", uid).eq("flag", 1));
        int num=0;
        //先去查每个食物列表

        for(Order order :orders){
            num=num+1;
        }
        return R.ok(num);
    }


}
